import type { UserBehavior } from '../types';
import type { ConfigManager } from './ConfigManager';
import type { PlatformAdapter } from './PlatformAdapter';

// 声明 uni 的类型
declare const uni: {
  switchTab: (options: any) => any;
  navigateTo: (options: any) => any;
  redirectTo: (options: any) => any;
  request: (options: any) => any;
};

export class ErrorCollector {
  private userBehaviors: UserBehavior[] = [];
  private maxBehaviorCount = 50;
  private sessionStartTime = Date.now();
  private pageStartTime = Date.now();
  private currentPage = '';
  private clickListeners: (() => void)[] = [];
  private originalUniRequest?: any;

  constructor(
    private configManager: ConfigManager,
    private platformAdapter: PlatformAdapter
  ) {}

  async init(): Promise<void> {
    const config = this.configManager.getConfig();
    
    if (config.enableAutoReport) {
      this.setupAutoErrorCapture();
    }
    
    if (config.enableUserBehavior) {
      this.setupBehaviorTracking();
      this.setupClickTracking();
      this.setupAPITracking();
      this.setupFormTracking();
      this.setupScrollTracking();
    }
  }

  private setupAutoErrorCapture(): void {
    this.platformAdapter.setupErrorHandlers((error: any, info?: any) => {
      // 记录错误发生时的行为
      this.recordBehavior('error', {
        error: error.message || error,
        stack: error.stack,
        info,
        pageStayTime: Date.now() - this.pageStartTime
      });
      console.log('Auto captured error:', error, info);
    });
  }

  private setupBehaviorTracking(): void {
    // 页面导航跟踪
    // #ifndef H5
    if (typeof uni !== 'undefined') {
      const originalSwitchTab = uni.switchTab;
      const originalNavigateTo = uni.navigateTo;
      const originalRedirectTo = uni.redirectTo;
      
      uni.switchTab = (options: any) => {
        this.recordPageLeave();
        this.recordBehavior('navigate', { 
          type: 'switchTab', 
          url: options.url,
          from: this.currentPage
        });
        this.updateCurrentPage(options.url);
        return originalSwitchTab(options);
      };
      
      uni.navigateTo = (options: any) => {
        this.recordPageLeave();
        this.recordBehavior('navigate', { 
          type: 'navigateTo', 
          url: options.url,
          from: this.currentPage
        });
        this.updateCurrentPage(options.url);
        return originalNavigateTo(options);
      };
      
      uni.redirectTo = (options: any) => {
        this.recordPageLeave();
        this.recordBehavior('navigate', { 
          type: 'redirectTo', 
          url: options.url,
          from: this.currentPage
        });
        this.updateCurrentPage(options.url);
        return originalRedirectTo(options);
      };
    }
    // #endif

    // H5环境的页面导航跟踪
    // #ifdef H5
    if (typeof window !== 'undefined') {
      // 监听页面可见性变化
      document.addEventListener('visibilitychange', () => {
        this.recordBehavior('visibility', {
          hidden: document.hidden,
          visibilityState: document.visibilityState
        });
      });
    
      // 监听页面卸载
      window.addEventListener('beforeunload', () => {
        this.recordPageLeave();
      });
    
      // 监听历史记录变化
      const originalPushState = history.pushState;
      const originalReplaceState = history.replaceState;
      const selfHistory = this; // 重命名避免冲突
      
      history.pushState = function(...args: [any, string, string?]) {
        selfHistory.recordPageLeave();
        selfHistory.recordBehavior('navigate', {
          type: 'pushState',
          url: args[2],
          from: window.location.href
        });
        selfHistory.updateCurrentPage(args[2] as string);
        return originalPushState.apply(history, args);
      };
    
      history.replaceState = function(...args: [any, string, string?]) {
        selfHistory.recordBehavior('navigate', {
          type: 'replaceState',
          url: args[2],
          from: window.location.href
        });
        selfHistory.updateCurrentPage(args[2] as string);
        return originalReplaceState.apply(history, args);
      };
    }
    // #endif
  }

  private setupClickTracking(): void {
    // #ifdef H5
    if (typeof document !== 'undefined') {
      const clickHandler = (event: MouseEvent) => {
        const target = event.target as HTMLElement;
        if (target) {
          this.recordBehavior('click', {
            tagName: target.tagName,
            className: target.className,
            id: target.id,
            text: target.textContent?.slice(0, 100),
            x: event.clientX,
            y: event.clientY,
            page: this.currentPage
          });
        }
      };
      
      document.addEventListener('click', clickHandler, true);
      this.clickListeners.push(() => {
        document.removeEventListener('click', clickHandler, true);
      });
    }
    // #endif

    // #ifndef H5
    // 小程序和App环境的点击追踪需要在组件级别实现
    // 这里提供一个手动记录的方法
    // #endif
  }

  private setupAPITracking(): void {
    // #ifndef H5
    if (typeof uni !== 'undefined') {
      this.originalUniRequest = uni.request;
      
      uni.request = (options: any) => {
        const startTime = Date.now();
        const requestId = Math.random().toString(36).substr(2, 9);
        const originalSuccess = options.success;
        const originalFail = options.fail;
        
        this.recordBehavior('api', {
          type: 'request_start',
          url: options.url,
          method: options.method || 'GET',
          requestId
        });
        
        options.success = (res: any) => {
          const duration = Date.now() - startTime;
          this.recordBehavior('api', {
            type: 'request_success',
            url: options.url,
            method: options.method || 'GET',
            requestId,
            statusCode: res.statusCode,
            duration
          });
          if (originalSuccess) originalSuccess(res);
        };
        
        options.fail = (err: any) => {
          const duration = Date.now() - startTime;
          this.recordBehavior('api', {
            type: 'request_fail',
            url: options.url,
            method: options.method || 'GET',
            requestId,
            error: err.errMsg,
            duration
          });
          if (originalFail) originalFail(err);
        };
        
        return this.originalUniRequest(options);
      };
    }
    // #endif

    // #ifdef H5
    if (typeof window !== 'undefined') {
      // 监听fetch请求
      const originalFetch = window.fetch;
      const selfFetch = this; // 重命名避免冲突
      
      window.fetch = async (...args) => {
        const startTime = Date.now();
        const requestId = Math.random().toString(36).substr(2, 9);
        // 修复URL获取逻辑 - 简化处理
        let url: string;
        if (typeof args[0] === 'string') {
          url = args[0];
        } else if (args[0] instanceof Request) {
          url = args[0].url;
        } else {
          url = String(args[0]);
        }
        const method = args[1]?.method || 'GET';
        
        selfFetch.recordBehavior('api', {
          type: 'fetch_start',
          url,
          method,
          requestId
        });
        
        try {
          const response = await originalFetch(...args);
          const duration = Date.now() - startTime;
          
          selfFetch.recordBehavior('api', {
            type: 'fetch_success',
            url,
            method,
            requestId,
            status: response.status,
            duration
          });
          
          return response;
        } catch (error) {
          const duration = Date.now() - startTime;
          
          selfFetch.recordBehavior('api', {
            type: 'fetch_fail',
            url,
            method,
            requestId,
            error: (error as Error).message,
            duration
          });
          
          throw error;
        }
      };
      
      // 监听XMLHttpRequest
      const originalXHROpen = XMLHttpRequest.prototype.open;
      const originalXHRSend = XMLHttpRequest.prototype.send;
      const selfXHR = this; // 重命名避免冲突
      
      XMLHttpRequest.prototype.open = function(method: string, url: string | URL, async?: boolean, username?: string | null, password?: string | null) {
        (this as any)._method = method;
        (this as any)._url = url;
        (this as any)._startTime = Date.now();
        (this as any)._requestId = Math.random().toString(36).substr(2, 9);
        
        return originalXHROpen.call(this, method, url, async ?? true, username, password);
      };
      
      XMLHttpRequest.prototype.send = function(data?: any) {
        const xhr = this as any;
        
        selfXHR.recordBehavior('api', {
          type: 'xhr_start',
          url: xhr._url,
          method: xhr._method,
          requestId: xhr._requestId
        });
        
        this.addEventListener('load', () => {
          const duration = Date.now() - xhr._startTime;
          selfXHR.recordBehavior('api', {
            type: 'xhr_success',
            url: xhr._url,
            method: xhr._method,
            requestId: xhr._requestId,
            status: this.status,
            duration
          });
        });
        
        this.addEventListener('error', () => {
          const duration = Date.now() - xhr._startTime;
          selfXHR.recordBehavior('api', {
            type: 'xhr_fail',
            url: xhr._url,
            method: xhr._method,
            requestId: xhr._requestId,
            duration
          });
        });
        
        return originalXHRSend.call(this, data);
      };
    }
    // #endif
  }

  private setupFormTracking(): void {
    // #ifdef H5
    if (typeof document !== 'undefined') {
      // 表单提交追踪
      const formSubmitHandler = (event: Event) => {
        const form = event.target as HTMLFormElement;
        if (form && form.tagName === 'FORM') {
          this.recordBehavior('form', {
            type: 'submit',
            action: form.action,
            method: form.method,
            formId: form.id,
            page: this.currentPage
          });
        }
      };
      
      document.addEventListener('submit', formSubmitHandler, true);
      this.clickListeners.push(() => {
        document.removeEventListener('submit', formSubmitHandler, true);
      });
      
      // 输入框焦点追踪
      const focusHandler = (event: FocusEvent) => {
        const target = event.target as HTMLElement;
        if (target && (target.tagName === 'INPUT' || target.tagName === 'TEXTAREA')) {
          this.recordBehavior('input', {
            type: 'focus',
            tagName: target.tagName,
            inputType: (target as HTMLInputElement).type,
            id: target.id,
            name: (target as HTMLInputElement).name,
            page: this.currentPage
          });
        }
      };
      
      document.addEventListener('focus', focusHandler, true);
      this.clickListeners.push(() => {
        document.removeEventListener('focus', focusHandler, true);
      });
    }
    // #endif
  }

  private setupScrollTracking(): void {
    // #ifdef H5
    if (typeof window !== 'undefined') {
      let scrollTimer: number | null = null;
      
      const scrollHandler = () => {
        if (scrollTimer) {
          clearTimeout(scrollTimer);
        }
        
        scrollTimer = setTimeout(() => {
          this.recordBehavior('scroll', {
            scrollX: window.scrollX,
            scrollY: window.scrollY,
            page: this.currentPage
          });
        }, 200) as any;
      };
      
      window.addEventListener('scroll', scrollHandler, { passive: true });
      this.clickListeners.push(() => {
        window.removeEventListener('scroll', scrollHandler);
        if (scrollTimer) clearTimeout(scrollTimer);
      });
    }
    // #endif
  }

  private updateCurrentPage(url: string): void {
    this.currentPage = url;
    this.pageStartTime = Date.now();
  }

  private recordPageLeave(): void {
    if (this.currentPage) {
      const stayTime = Date.now() - this.pageStartTime;
      this.recordBehavior('page', {
        type: 'leave',
        url: this.currentPage,
        stayTime
      });
    }
  }

  // 公共方法：手动记录用户行为
  recordCustomBehavior(type: string, data: Record<string, any>): void {
    this.recordBehavior('custom', {
      customType: type,
      ...data,
      page: this.currentPage
    });
  }

  // 公共方法：记录用户点击（用于小程序和App）
  recordClick(elementInfo: {
    type: string;
    id?: string;
    text?: string;
    [key: string]: any;
  }): void {
    this.recordBehavior('click', {
      ...elementInfo,
      page: this.currentPage
    });
  }

  recordBehavior(type: UserBehavior['type'], data: Record<string, any>): void {
    const behavior: UserBehavior = {
      type,
      timestamp: Date.now(),
      data: {
        ...data,
        sessionTime: Date.now() - this.sessionStartTime
      }
    };
    
    this.userBehaviors.push(behavior);
    
    // 保持行为记录数量在限制范围内
    if (this.userBehaviors.length > this.maxBehaviorCount) {
      this.userBehaviors.shift();
    }
  }

  getUserBehavior(): UserBehavior[] {
    return [...this.userBehaviors];
  }

  // 获取用户会话信息
  getSessionInfo(): {
    sessionStartTime: number;
    currentPage: string;
    sessionDuration: number;
    behaviorCount: number;
  } {
    return {
      sessionStartTime: this.sessionStartTime,
      currentPage: this.currentPage,
      sessionDuration: Date.now() - this.sessionStartTime,
      behaviorCount: this.userBehaviors.length
    };
  }

  destroy(): void {
    // 记录会话结束
    this.recordPageLeave();
    this.recordBehavior('session', {
      type: 'end',
      duration: Date.now() - this.sessionStartTime
    });
    
    // 清理事件监听器
    this.clickListeners.forEach(cleanup => cleanup());
    this.clickListeners = [];
    
    // 恢复原始的uni.request
    // #ifndef H5
    if (this.originalUniRequest && typeof uni !== 'undefined') {
      uni.request = this.originalUniRequest;
    }
    // #endif
    
    this.userBehaviors = [];
  }
}